/***************************************************************************

    debugstreams.cpp	- my logging class, see header

 ***************************************************************************/



#include "debugstreams.h"

#ifndef NDEBUG

DebugLevelType Debug::itsLevel = INFO;

bool Debug::IsActive = false;

CColor Debug::Default = CColor(DEFAULT_COLOR, DEFAULT_COLOR, ATTRIB_NONE);
CColor Debug::Tab[12] =
  {
    CColor(DEFAULT_COLOR, DEFAULT_COLOR, ATTRIB_NONE  ), // ALL
    CColor(DEFAULT_COLOR, DEFAULT_COLOR, ATTRIB_NONE  ), // MEM
    CColor(CYAN         , DEFAULT_COLOR, ATTRIB_NONE  ), // DEBUG
    CColor(GREEN        , DEFAULT_COLOR, ATTRIB_NONE  ), // LFUNC
    CColor(YELLOW       , DEFAULT_COLOR, ATTRIB_NONE  ), // LINFO
    CColor(BLUE         , DEFAULT_COLOR, ATTRIB_NONE  ), // FUNC
    CColor(DEFAULT_COLOR, DEFAULT_COLOR, ATTRIB_ITALIC), // INFO
    CColor(DEFAULT_COLOR, DEFAULT_COLOR, ATTRIB_NONE  ), // BLANK
    CColor(DEFAULT_COLOR, DEFAULT_COLOR, ATTRIB_NONE  ), // PROGRESS
    CColor(DEFAULT_COLOR, DEFAULT_COLOR, ATTRIB_NONE  ), // RELEASE
    CColor(RED          , DEFAULT_COLOR, ATTRIB_NONE  ), // WARN
    CColor(WHITE        , RED          , ATTRIB_BLINK ), // ERR
  };

Debug::Debug()
{
}

Debug::~Debug()
{
}

ostream& Debug::operator() (const DebugLevelType& Level)
{
  if (Level < itsLevel)
    // just ignore these messages
    return nullstream; // a stream with no output, very quick
  
  if (IsActive)
    return clog << Tab[Level].getColorCode();
  else
    Toggle(true);

  switch(Level)
    {
    case ALL:
      clog << Tab[Level].getColorCode() << "       : ";
      break;
    case MEM:
      clog << Tab[Level].getColorCode() << "    MEM : ";
      break;
    case FUNC:
    case LFUNC:
      clog << Tab[Level].getColorCode() << "  FUNC : ";
      break;
    case BLANK:
      break;
    case DEBUG: 
      cerr << Tab[Level].getColorCode() << "     DEBUG : ";
      return cerr;
      break;
    case INFO:
    case LINFO:
    case RELEASE:
      clog << Tab[Level].getColorCode() << "  INFO : ";
      return clog;
      break;
    case PROGRESS:
      cout << Tab[Level].getColorCode() << "        ";
      return cout;
      break;
    case WARN:
      clog << Tab[Level].getColorCode() << "WARN   : " << "";
      return clog;
      break;
    case ERR:
      cerr << Tab[Level].getColorCode() << "ERR    : " << ""; //^G is a beep
      return cerr;
      break;
    default:
      break;
    }
  return clog << Tab[Level].getColorCode();
}

string Debug::printLevel()
{
  switch (itsLevel)
    {
    case ALL:
      return string("ALL");
      break;
    case DEBUG:
      return string("DEBUG");
      break;		
    case LINFO:
      return string("LINFO");
      break;	 
    case LFUNC:
      return string("LFUNC");
      break;	 
    case FUNC:
      return string("FUNC");
      break;	 
    case MEM:
      return string("MEM");
      break;	 
    case BLANK:
    case INFO:
      return string("INFO");
      break;	 
    case PROGRESS:
      return string("PROGRESS");
      break;	 
    case RELEASE:
      return string("RELEASE");
      break;	 
    case WARN:
      return string("WARN");
      break;	 
    case ERR:
      return string("ERR");
      break;	 
    default:
      return string("UNKNOWN!!!!!!");
    }
}

DebugLevelType Debug::getLevel() const
{
    return itsLevel;
}

void Debug::setLevel(const DebugLevelType& Level)
{
  itsLevel = Level;
  //clog << "   INFO : DebugLevel set to : " << printLevel() << endl;
}


void Debug::Toggle(const bool& value)
{
  IsActive = value;
}

/*******************************************************************************
 *
 * Here we define some useful functions
 *
 ******************************************************************************/
ostream& error()
{
  return dout(ERR);
}

ostream& warning()
{
  return dout(WARN);
}

ostream& blank()
{
  return dout(BLANK);
}

ostream& info()
{
  return dout(INFO);
}

ostream& func()
{
  return dout(FUNC);
}

ostream& linfo()
{
  return dout(LINFO);
}

ostream& lfunc()
{
  return dout(LFUNC);
}

ostream& debug()
{
  return dout(DEBUG);
}

ostream& endreq(ostream& os)
{
  os << Debug::Default.getColorCode() << endl << flush;
  Debug::Toggle(false);
  return os;
}

#endif
